﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;
using System.Reflection;
using CS_NumberPlateReader.Properties;

namespace CS_NumberPlateReader
{
    class GRAData
    {
        public string Time = "";
        public string PlateNumber = "";
        public List<Rectangle> RectAreaList = new List<Rectangle>();
    }

    class GRADataManager
    {
        private static String filename_Index = "mok.gri";
        private static String filename_GRAData = "jb.gra";
        private static StringBuilder strLog = new StringBuilder();
        private static StringBuilder strProtocol = new StringBuilder();
        private const String directory_GRA = "GRA";
        private static String path_Assembly = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase).Substring(6);

        public static string GetSourceDataDirectory()
        {
#if DEBUG
            string path_data = path_Assembly;
#else
            string path_data = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData);
#endif
            string filename_path = path_data + "\\nprdat.dat";

            if (File.Exists(filename_path))
            {
                string path = fileData(filename_path);
                path = path.Substring(0, path.IndexOf('\0'));
                return Crypt.DESDecrypt(path);
            }
            else
            {
                return path_Assembly + "\\SourceData";
            }
        }

        public static void SetSourceDataDirectory(string path)
        {
#if DEBUG
            string path_data = path_Assembly;
#else
            string path_data = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData);
#endif
            string filename_path = path_data + "\\nprdat.dat";

            FileStream fs;
            fs = new FileStream(filename_path, FileMode.Create);
            fs.Seek(0, SeekOrigin.Begin);

            string appendString = Crypt.DESEncrypt(path);
            WriteStringBytes(appendString, fs);

            fs.Flush();
            fs.Close();
        }

        public static GRAData GetPlateInfo_Image(string filename)
        {
            int index = GetDataIndex(filename);

            if (index > -1)
            {
                string rawData = GetGRAData(index);
                if (rawData.Equals(""))
                {
                    return null;
                }

                string[] graData = rawData.Split('|');
                GRAData plateInfo = new GRAData();

                plateInfo.Time = graData[0].Substring(0, 2) + ":" + graData[0].Substring(2, 2) + ":" + graData[0].Substring(4, 2);
                plateInfo.PlateNumber = Crypt.DESDecrypt(graData[1]);
                string[] rectData = graData[2].Split('+');

                foreach (string info in rectData)
                {
                    string[] posData = info.Split('\\');
                    Rectangle rect = new Rectangle(Convert.ToInt32(posData[0]), Convert.ToInt32(posData[1]), Convert.ToInt32(posData[2]), Convert.ToInt32(posData[3]));
                    plateInfo.RectAreaList.Add(rect);
                }

                return plateInfo;
            }

            return null;
        }

        public static void SetPlateInfo_Image(string filename, GRAData data)
        {
            int index = GetDataIndex(filename);

            if (index == -1)
            {
                index = GetNewIndex();

                SetGRAData(data);
                SetDataIndex(filename, index);
            }
        }

        //Working...
        public static List<GRAData> GetPlateInfo_Video(string filename)
        {
            List<GRAData> lstInfo = new List<GRAData>();


            int index = GetDataIndex(filename);

            if (index > -1)
            {
                GRAData plateInfo = new GRAData();


            }

            return lstInfo;
        }

        private static int GetDataIndex(string filename)
        {
            int index = -1;
            //string filename_id = path_Assembly + "\\" + filename_Index;

            //if (File.Exists(filename_id))
            {
                string encrypted = Crypt.DESEncrypt(filename);
                //string indexdata = fileData(filename_id);
                string indexdata = fileData(Resources.mok);

                int indexOfIndex = indexdata.IndexOf(encrypted);
                if (indexOfIndex > -1)
                {
                    indexdata = indexdata.Substring(indexOfIndex, encrypted.Length + 4);
                    indexdata = indexdata.Substring(encrypted.Length, 4);

                    index = Convert.ToInt32(indexdata);
                }
            }

            return index;
        }

        private static void SetDataIndex(string filename, int index)
        {
            string filename_id = path_Assembly + "\\" + filename_Index;
            string encrypted = Crypt.DESEncrypt(filename);

            FileStream fs;

            if (File.Exists(filename_id))
            {
                fs = new FileStream(filename_id, FileMode.Append);
                fs.Seek(0, SeekOrigin.End);
            }
            else
            {
                fs = new FileStream(filename_id, FileMode.Create);
                fs.Seek(0, SeekOrigin.Begin);
            }

            string appendString = encrypted + index.ToString("D4");
            WriteStringBytes(appendString, fs);

            fs.Flush();
            fs.Close();
        }

        private static string GetGRAData(int index)
        {
            //string filename_data = path_Assembly + "\\" + filename_GRAData;

            //if (File.Exists(filename_data))
            {
                //string filedata = fileData(filename_data);
                string filedata = fileData(Resources.jb);
                string[] datas = filedata.Split(' ');
                return datas[index];
            }

            //return "";
        }

        private static void SetGRAData(GRAData data)
        {
            string filename_data = path_Assembly + "\\" + filename_GRAData;

            FileStream fs;
            String appendString = data.Time.Substring(0, 2);
            appendString += data.Time.Substring(3, 2);
            appendString += data.Time.Substring(6, 2) + "|";
            appendString += Crypt.DESEncrypt(data.PlateNumber) + "|";

            foreach (Rectangle rect in data.RectAreaList)
            {
                appendString += rect.X.ToString() + "\\" + rect.Y.ToString() + "\\" + rect.Width.ToString() + "\\" + rect.Height.ToString() + "+";
            }

            if (appendString.Substring(appendString.Length - 1).Equals("+"))
            {
                appendString = appendString.Substring(0, appendString.Length - 1);
            }

            appendString += " ";


            if (File.Exists(filename_data))
            {
                fs = new FileStream(filename_data, FileMode.Append);
                fs.Seek(0, SeekOrigin.End);
            }
            else
            {
                fs = new FileStream(filename_data, FileMode.Create);
                fs.Seek(0, SeekOrigin.Begin);
            }

            WriteStringBytes(appendString, fs);

            fs.Flush();
            fs.Close();
        }

        private static int GetNewIndex()
        {
            //string filename_data = path_Assembly + "\\" + filename_GRAData;

            //if (File.Exists(filename_data))
            {
                //string filedata = fileData(filename_data);
                string filedata = fileData(Resources.jb);
                filedata = filedata.Substring(0, filedata.IndexOf('\0') - 1);
                string[] datas = filedata.Split(' ');
                return datas.Length;
            }

            //return 0;
        }

        private static string fileData(byte[] file)
        {
            return new UTF8Encoding(true).GetString(file);
        }

        private static string fileData(string filename)
        {
            FileStream fs;

            if (File.Exists(filename))
            {
                fs = new FileStream(filename, FileMode.Open);
                fs.Seek(0, SeekOrigin.Begin);
                byte[] data = new byte[40960];
                fs.Read(data, 0, 40960);
                fs.Close();

                return new UTF8Encoding(true).GetString(data);
            }

            return string.Empty;
        }

        public static byte[] WriteStringBytes(String str, FileStream fs)
        {
            byte[] info = new UTF8Encoding(true).GetBytes(str);
            fs.Write(info, 0, info.Length);

            return info;
        }    
    }
}
